package com.cskaoyan.controller;

import com.cskaoyan.bean.model.*;
import com.cskaoyan.bean.req.CartAddVo;
import com.cskaoyan.bean.req.CartCheckedVo;
import com.cskaoyan.bean.resp.BaseRespVo;
import com.cskaoyan.bean.resp.CartCheckoutVo;
import com.cskaoyan.bean.resp.CartData;
import com.cskaoyan.service.*;
import com.cskaoyan.util.StringUtil;
import com.cskaoyan.util.SystemConfig;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

@RestController
@RequestMapping("/wx/cart")
public class WxCartController {
    @Autowired
    private CartService cartService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private GoodsProductService productService;
    @Autowired
    private AddressService addressService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private CouponUserService couponUserService;

    @GetMapping("/index")
    public BaseRespVo index() {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        if (userId == null) {
            return BaseRespVo.unAuthen();
        }
        CartData cartData = cartService.index(userId);
        return BaseRespVo.ok(cartData);
    }

    @GetMapping("goodscount")
    public BaseRespVo goodsCount() {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        if (userId == null) {
            return BaseRespVo.unAuthen();
        }
        long goodsCount = cartService.goodsCount(userId);
        return BaseRespVo.ok(goodsCount);
    }

    @PostMapping("/add")
    public BaseRespVo add(@RequestBody CartAddVo cartAddVo) {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        if (userId == null) {
            return BaseRespVo.unAuthen();
        }
        return add(cartAddVo, userId,false);
    }

    @PostMapping("fastadd")
    public BaseRespVo fastadd(@RequestBody CartAddVo cartAddVo) {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        if (userId == null) {
            return BaseRespVo.unAuthen();
        }
        return add(cartAddVo, userId,true);
    }

    @PostMapping("checked")
    public BaseRespVo checked(@RequestBody CartCheckedVo cartCheckedVo) {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        if (userId == null) {
            return BaseRespVo.unAuthen();
        }
        cartService.checked(cartCheckedVo,userId);
        return BaseRespVo.ok(cartService.index(userId));
    }

    @GetMapping("checkout")
    public BaseRespVo checkout(Integer cartId,Integer addressId,Integer couponId,Integer userCouponId) {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        if (userId == null) {
            return BaseRespVo.unAuthen();
        }
        // cartId为0 则是购物车中所有的已经选中的当前用户的记录要执行下单
        // cartId不为0，则是当前购物车记录做下单
        List<MarketCart> carts = cartService.findById(cartId, userId);
        MarketAddress address = addressService.findById(addressId, userId);

        // 如果couponId和userCouponId为0，则查询满足条件的最大金额的优惠券
        // 如果couponId和userCouponId为-1，则查询满足条件的优惠券数量
        // 如果couponId和userCouponId既不为0又不为-1，查询当前优惠券（是否可用）
        // 要完成上面的业务，要先统计货品的总价
        BigDecimal totalPrice = carts.stream().map(cart -> {
            // 单个cart记录的单价和数量做相乘
            Short number = cart.getNumber();
            BigDecimal price = cart.getPrice();
            BigDecimal multiply = price.multiply(new BigDecimal(number));
            return multiply; // 单个cart里的乘积，还要做累加 → reduce
        }).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 获取总价之后就可以做优惠券的查询，还可以做满减运费
        if (totalPrice.compareTo(BigDecimal.ZERO) == 0) {
            return BaseRespVo.err("请先选择购物商品");
        }
        // 默认运费设置为0
        BigDecimal freightPrice = new BigDecimal(0);
        // 如果不满足满减金额
        if (totalPrice.compareTo(SystemConfig.getExpressFreightMin()) < 0) {
            // 赋值运费
            freightPrice = SystemConfig.getExpressFreightValue();
        }

        //List<MarketGoods> goodsList = goodsService.queryByCart(carts);

        BigDecimal couponPrice = new BigDecimal(0);
        int availableCouponLength = 0;
        if (userCouponId != 0 && couponId != -1) {
            // 查询当前优惠券
            MarketCoupon coupon = couponService.findById(couponId);
            MarketCouponUser couponUser = couponUserService.findById(userCouponId,userId);
            if (coupon != null && couponUser != null && totalPrice.compareTo(coupon.getMin()) > 0) {
                couponPrice = coupon.getDiscount();
            }

        }else {
            // 查询所有优惠券
            //List<MarketCoupon> couponList =  couponService.list(totalPrice);
            List<MarketCouponUser> couponUserList = couponUserService.list(totalPrice,userId);
            availableCouponLength = couponUserList.size();
            if (couponId != null && couponId.intValue() == 0 && availableCouponLength > 0) {
                MarketCouponUser maxDiscountCouponUser = couponUserList.get(0);
                couponId = maxDiscountCouponUser.getCouponId();
                userCouponId = maxDiscountCouponUser.getId();
                couponPrice = couponService.findById(couponId).getDiscount();
            }
        }
        BigDecimal orderTotalPrice = totalPrice.add(freightPrice).subtract(couponPrice);
        orderTotalPrice = orderTotalPrice.compareTo(BigDecimal.ZERO) >= 0 ? orderTotalPrice : BigDecimal.ZERO;
        CartCheckoutVo data = CartCheckoutVo.builder()
                .goodsTotalPrice(totalPrice)
                .freightPrice(freightPrice)
                .addressId(address == null ? 0 : address.getId())
                .availableCouponLength(availableCouponLength) // todo：查询当前用户的可用优惠券
                .cartId(cartId)
                .checkedAddress(address)
                .checkedGoodsList(carts) // todo:carts中的List<MarketGoods>
                .couponId(couponId) // todo：查询当前用户的优惠券
                .couponPrice(couponPrice) // todo：查询当前用户的优惠券
                .userCouponId(userCouponId) // todo：查询当前用户的优惠券
                .orderTotalPrice(orderTotalPrice)
                .actualPrice(orderTotalPrice)
                .build();


        return BaseRespVo.ok(data);
    }

    private BaseRespVo add(CartAddVo cartAddVo, Integer userId,boolean fast) {
        //判断商品是否可以购买
        Integer goodsId = cartAddVo.getGoodsId();
        Integer productId = cartAddVo.getProductId();
        Short number = cartAddVo.getNumber();

        MarketCart cart = MarketCart.builder().goodsId(goodsId).productId(productId).number(number).build();

        MarketGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return BaseRespVo.err("商品已下架");
        }

        MarketGoodsProduct product = productService.findById(productId);
        //判断购物车中是否存在此规格商品 → 如果有记录则更新number；如果没有则新增cart记录
        MarketCart existCart = cartService.queryExist(goodsId, productId, userId);
        if (existCart == null) { // 没有的话增加记录
            //取得规格的信息,判断规格库存
            if (product == null || number > product.getNumber()) {
                return BaseRespVo.msg( "库存不足");
            }

            cart.setId(null);
            cart.setGoodsSn(goods.getGoodsSn());
            cart.setGoodsName((goods.getName()));
            if(StringUtil.isEmpty(product.getUrl())){
                cart.setPicUrl(goods.getPicUrl());
            }
            else{
                cart.setPicUrl(product.getUrl());
            }
            cart.setPrice(product.getPrice());
            cart.setSpecifications(product.getSpecifications());
            cart.setUserId(userId);
            cart.setChecked(true);
            cartService.create(cart);
        } else { // 如果有的话，就更新数量
            //取得规格的信息,判断规格库存
            int num = existCart.getNumber() + number;
            if (num > product.getNumber()) {
                return BaseRespVo.err( "库存不足");
            }
            existCart.setNumber((short) num);
            if (cartService.updateById(existCart) == 0) {
                return BaseRespVo.err("更新失败");
            }
        }
        if (fast) { // fastadd返回时的新增的购物车记录的主键
            Integer cartId = existCart == null ? cart.getId() : existCart.getId();
            return BaseRespVo.ok(cartId);
        } else { //add返回的是当前用户的购物车中的货品数
            return BaseRespVo.ok(cartService.goodsCount(userId));
        }
    }
}
